home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
OPTIONS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-28
|
4KB
|
203 lines
/*
* generic option parsing
*
* (c) Copyright 1988, Kim F. Storm, storm@texas.dk
*/
#include "config.h"
#include "options.h"
static char **save_argv, *usage_mesg;
static struct option_descr *save_optd;
char *program_name(av)
char **av;
{
char *cp;
/* skip "/path/" part of program name */
if (cp = strrchr(*av, '/'))
return cp + 1;
else
return *av;
}
parse_options(ac, av, envname, options, usage)
int ac;
char **av, *envname;
struct option_descr options[];
char *usage;
{
register char *cp, opt;
register struct option_descr *od;
extern int atoi();
int files;
char **names;
char *envinit;
save_argv = av;
save_optd = options;
if (options == NULL) return 0;
usage_mesg = usage;
--ac;
names = ++av;
files = 0;
envinit = envname ? getenv(envname) : NULL;
cp = envinit;
next_option:
if (envinit) {
while (*cp && isspace(*cp)) cp++;
if (*cp == '-') {
cp++;
goto next_option;
}
if (*cp == NUL) {
envinit = NULL;
goto next_option;
}
} else
if (cp == NULL || *cp == NUL) {
if ((cp = *av++) == NULL) {
*names = NULL;
return files;
}
ac--;
if (*cp != '-') {
*names++ = cp;
cp = NULL;
files++;
goto next_option;
}
cp++; /* skip - */
}
opt = *cp++;
for (od = options; od->option_letter; od++) {
if (od->option_letter != opt) continue;
switch (od->option_type) {
case 1: /* BOOL_OPTION */
*((int *)(od->option_address)) = !*((int *)(od->option_address));
goto next_option;
case 2: /* STRING_OPTION */
case 3: /* OPTIONAL_STRING */
/* -oSTR or -o STR */
while (*cp && isspace(*cp)) cp++;
if (*cp == NUL) {
if (envinit || ac == 0) {
if (od->option_type == 3) goto opt_str;
error("missing string argumet to -%c", opt);
}
cp = *av++;
ac--;
}
if (od->option_type == 3 && *cp == '-') goto opt_str;
*(od->option_address) = cp;
if (envinit) {
while (*cp && !isspace(*cp)) cp++;
if (*cp) *cp++ = NUL;
} else
cp = NULL;
goto next_option;
opt_str:
*(od->option_address) = od->option_default;
goto next_option;
case 4:
case 5:
/* -oN or -o N */
while (*cp && isspace(*cp)) cp++;
if (*cp) {
if (!isdigit(*cp)) {
if (od->option_type == 5) goto opt_int;
error("non-numeric argument to -%c", opt);
}
} else {
if (envinit || ac == 0 || !isdigit(**av)) {
if (od->option_type == 5) goto opt_int;
error("missing argument to -%c", opt);
}
cp = *av++;
ac--;
}
*((int *)(od->option_address)) = atoi(cp);
while (isdigit(*cp)) cp++;
goto next_option;
opt_int:
*((int *)(od->option_address)) = (int)(od->option_default);
goto next_option;
}
}
error("unknown option '-%c'", opt);
/*NOTREACHED*/
}
static error(message, option_letter)
char *message, option_letter;
{
char *prog_name = program_name(save_argv);
fprintf(stderr, "%s: ", prog_name);
fprintf(stderr, message, option_letter);
fputc('\n', stderr);
fprintf(stderr, "usage: %s", prog_name);
dump_options(1, "");
dump_options(2, " STR");
dump_options(3, " [STR]");
dump_options(4, " NUM");
dump_options(5, " [NUM]");
if (usage_mesg) fprintf(stderr, usage_mesg);
fputc(NL, stderr);
nn_exit(9);
}
static dump_options(type, tail)
int type;
char *tail;
{
register struct option_descr *od;
int any = 0;
for (od = save_optd; od->option_letter; od++) {
if (od->option_type != type) continue;
fprintf(stderr, any ? "%c" : " -%c", od->option_letter );
any++;
}
if (any && tail && tail[0]) {
fprintf(stderr, "%s", tail);
}
}